package handlers

import (
	"github.com/gin-gonic/gin"
	"github.com/morgine/redirect/internal/http/message"
	"github.com/morgine/redirect/internal/model"
	"gorm.io/gorm"
)

type Redirect struct {
	message.Sender
	db *model.DB
}

func NewRedirect(db *gorm.DB) *Redirect {
	mdb := model.NewDB(db)
	return &Redirect{
		Sender: message.Sender{},
		db:     mdb,
	}
}

func (r *Redirect) GetGroups() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		groups, err := r.db.GetGroups()
		if err != nil {
			r.SendError(ctx, err)
		} else {
			r.SendJSON(ctx, groups)
		}
	}
}

func (r *Redirect) SaveGroup() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		var ps = &model.Group{}
		err := ctx.Bind(ps)
		if err != nil {
			r.SendError(ctx, err)
		} else {
			err := r.db.SaveGroup(ps)
			if err != nil {
				r.SendError(ctx, err)
			} else {
				r.SendJSON(ctx, ps)
			}
		}
	}
}

func (r *Redirect) DelGroup() gin.HandlerFunc {
	type params struct {
		ID int
	}
	return func(ctx *gin.Context) {
		ps := &params{}
		err := ctx.Bind(ps)
		if err != nil {
			r.SendError(ctx, err)
		} else {
			err = r.db.DeleteGroup(ps.ID)
			if err != nil {
				r.SendError(ctx, err)
			} else {
				r.SendSuccessMessage(ctx, "已删除")
			}
		}
	}
}

func (r *Redirect) GetLinks() gin.HandlerFunc {
	type params struct {
		GroupID int
	}
	return func(ctx *gin.Context) {
		ps := &params{}
		err := ctx.Bind(ps)
		if err != nil {
			r.SendError(ctx, err)
		}
		destinations, err := r.db.GetLinks(ps.GroupID)
		if err != nil {
			r.SendError(ctx, err)
		} else {
			r.SendJSON(ctx, destinations)
		}
	}
}

func (r *Redirect) SaveLink() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		var ps = &model.Link{}
		err := ctx.Bind(ps)
		if err != nil {
			r.SendError(ctx, err)
		} else {
			err := r.db.SaveLink(ps)
			if err != nil {
				r.SendError(ctx, err)
			} else {
				r.SendJSON(ctx, ps)
			}
		}
	}
}

func (r *Redirect) DelLinks() gin.HandlerFunc {
	type params struct {
		GroupID int
		IDs     []int
	}
	return func(ctx *gin.Context) {
		ps := &params{}
		err := ctx.Bind(ps)
		if err != nil {
			r.SendError(ctx, err)
		} else {
			err = r.db.DeleteLinks(ps.GroupID, ps.IDs)
			if err != nil {
				r.SendError(ctx, err)
			} else {
				r.SendSuccessMessage(ctx, "已删除")
			}
		}
	}
}

func (r *Redirect) GetCurrentLink() gin.HandlerFunc {
	type params struct {
		ID int
	}
	return func(ctx *gin.Context) {
		ps := &params{}
		err := ctx.Bind(ps)
		if err != nil {
			r.SendError(ctx, err)
		} else {
			url := r.db.GetCurrentDestination(ps.ID)
			if url != nil {
				ctx.Redirect(302, *url)
			} else {
				ctx.Writer.WriteString("该地址已失效")
			}
		}
	}
}

func (r *Redirect) Close() {
	r.db.Close()
}
